﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
using CAION2.Classes;
using CAION2.Commands;
using CAION2.Models;
using CAION2.Properties;
using CAION2.Views;
using FirstFloor.ModernUI.Windows.Controls;
using CAION2.Helpers;

namespace CAION2.ViewModels
{
    using FirstFloor.ModernUI.Presentation;

    using RelayCommand = RelayCommand;

    public class Card3ViewModel : ViewModelBase
    {
        public class StatsValuesClass
        {
            public string Stat;

            public string Translate;

            public string Unit;

            public Single BasicValue;

            public Single BasicValue2;

            public Single BonusValue;

            public Single EnchantValue;

            public Single ManaStoneValue;

            public Single RandomBonusValue;

            public Single IdianValue;

            public Single GodEnchantValue;

            public Single ArmsfusionBonusValue;

            public Single ArmsfusionManaStoneValue;

            public String Tips;


            public StatsValuesClass()
            {
                
            }

            public StatsValuesClass(char valueId, string stat, Single value, Single value2 = 0, string unit = "")
            {
                this.Stat = stat;
                this.Translate = CardStat.GetStatTranslate(this.Stat);
                this.Unit = unit;

                switch (valueId)
                {
                    case 'e':
                        this.EnchantValue = value;
                        break;
                    case 'm':
                        this.ManaStoneValue = value;
                        break;
                    case 'b':
                        this.BonusValue = value;
                        break;
                    case 'r':
                        this.RandomBonusValue = value;
                        break;
                    case 'i':
                        this.IdianValue = value;
                        break;
                    case 'g':
                        this.GodEnchantValue = value;
                        break;
                    case 'a':
                        this.ArmsfusionBonusValue = value;
                        break;
                    case 'n':
                        this.ArmsfusionManaStoneValue = value;
                        break;
                    case 'x':
                        this.BasicValue = value;
                        this.BasicValue2 = value2;
                        break;
                }
            }

            public void UpdateStatValue(
                char valueId,
                Single value,
                Single value2 = 0,
                EnchantStates state = EnchantStates.Value,
                string unit = "")
            {
                if (!string.IsNullOrEmpty(unit)) this.Unit = unit;

                switch (state)
                {
                    case EnchantStates.Value:
                        switch (valueId)
                        {
                            case 'e':
                                this.EnchantValue = value;
                                break;
                            case 'm':
                                this.ManaStoneValue = value;
                                break;
                            case 'b':
                                this.BonusValue = value;
                                break;
                            case 'r':
                                this.RandomBonusValue = value;
                                break;
                            case 'i':
                                this.IdianValue = value;
                                break;
                            case 'g':
                                this.GodEnchantValue = value;
                                break;
                            case 'a':
                                this.ArmsfusionBonusValue = value;
                                break;
                            case 'n':
                                this.ArmsfusionManaStoneValue = value;
                                break;
                            case 'x':
                                this.BasicValue = value;
                                this.BasicValue2 = value2;
                                break;
                        }
                        break;
                    case EnchantStates.Plus:
                        switch (valueId)
                        {
                            case 'e':
                                this.EnchantValue += value;
                                break;
                            case 'm':
                                this.ManaStoneValue += value;
                                break;
                            case 'b':
                                this.BonusValue += value;
                                break;
                            case 'r':
                                this.RandomBonusValue += value;
                                break;
                            case 'i':
                                this.IdianValue += value;
                                break;
                            case 'g':
                                this.GodEnchantValue += value;
                                break;
                            case 'a':
                                this.ArmsfusionBonusValue += value;
                                break;
                            case 'n':
                                this.ArmsfusionManaStoneValue += value;
                                break;
                            case 'x':
                                this.BasicValue += value;
                                this.BasicValue2 += value2;
                                break;
                        }
                        break;
                    case EnchantStates.Minus:
                        switch (valueId)
                        {
                            case 'e':
                                this.EnchantValue -= value;
                                break;
                            case 'm':
                                this.ManaStoneValue -= value;
                                break;
                            case 'b':
                                this.BonusValue -= value;
                                break;
                            case 'r':
                                this.RandomBonusValue -= value;
                                break;
                            case 'i':
                                this.IdianValue -= value;
                                break;
                            case 'g':
                                this.GodEnchantValue -= value;
                                break;
                            case 'a':
                                this.ArmsfusionBonusValue -= value;
                                break;
                            case 'n':
                                this.ArmsfusionManaStoneValue -= value;
                                break;
                            case 'x':
                                this.BasicValue -= value;
                                this.BasicValue2 -= value2;
                                break;
                        }
                        break;
                }
            }

            public Single Sum()
            {
                return this.EnchantValue 
                    + this.ManaStoneValue 
                    + this.BonusValue 
                    + this.RandomBonusValue 
                    + this.IdianValue 
                    + this.GodEnchantValue
                    + this.ArmsfusionBonusValue
                    + this.ArmsfusionManaStoneValue;
            }

            public string BasicValueText()
            {
                if (Math.Abs(this.BasicValue) <= 0) return "";
                if (this.BasicValue2 > 0) return this.BasicValue + " - " + this.BasicValue2;
                return this.BasicValue.ToString(CultureInfo.InvariantCulture);
            }

            public string SumValueText()
            {
                Single sum = this.Sum();
                if (Math.Abs(sum) <= 0) return "";

                string sign = "+";
                if (sum < 0) sign = "";

                if (this.BasicValue > 0)
                {
                    return "[color=" + AppearanceManager.Current.AccentColor + "] " + sign + sum + this.Unit + "[/color]";
                }
                return "[color=" + AppearanceManager.Current.AccentColor + "]" + sign + sum + this.Unit + "[/color]";
            }

            public StatsValuesClass Clone()
            {
                return new StatsValuesClass
                                          {
                                              Stat = this.Stat,
                                              Translate = this.Translate,
                                              Unit = this.Unit,
                                              BasicValue = this.BasicValue,
                                              BasicValue2 = this.BasicValue2,
                                              BonusValue = this.BonusValue,
                                              EnchantValue = this.EnchantValue,
                                              ManaStoneValue = this.ManaStoneValue,
                                              RandomBonusValue = this.RandomBonusValue,
                                              IdianValue = this.IdianValue,
                                              GodEnchantValue = this.GodEnchantValue,
                                              ArmsfusionBonusValue = this.ArmsfusionBonusValue,
                                              ArmsfusionManaStoneValue =
                                                  this.ArmsfusionManaStoneValue,
                                              Tips = this.Tips
                                          };
            }
        }

        public enum EnchantStates
        {
            Value,

            Plus,

            Minus
        }

        

        #region Vars & Properties

            #region General
        
        private List<StatsValuesClass> statsList;
        private bool firstPageChecked;

        private String fullCharacters;
        private String fullCharacters2;
        private String mainCharacters;

        private ObservableCollection<Visibility> pagesVisible;
        private byte placeIndex;
        private bool isCraftItem;

        private string translateName;
        private SolidColorBrush translateColor;

        private static readonly List<string> JewelMarks = new List<string>
                                                          {
                                                              "right_or_left_ear",
                                                              "neck",
                                                              "right_or_left_finger",
                                                              "waist"
                                                          };

        public Visibility CardVisible
        {
            get
            {
                return this.cardVisible;
            }
            set
            {
                if (Equals(this.cardVisible, value)) return;

                this.cardVisible = value;
                this.OnPropertyChanged("CardVisible");
            }
        }

        public ObservableCollection<Visibility> PagesVisible
        {
            get
            {
                return this.pagesVisible;
            }
            private set
            {
                if (Equals(this.pagesVisible, value)) return;

                this.pagesVisible = value;
                this.OnPropertyChanged("PagesVisible");
            }
        }

        public bool FirstPageChecked
        {
            get
            {
                return this.firstPageChecked;
            }
            set
            {
                this.firstPageChecked = value;
                this.OnPropertyChanged("FirstPageChecked");
            }
        }

        public bool CardIsLoaded { get; private set; }

        public byte PlaceIndex
        {
            private get
            {
                return this.placeIndex;
            }
            set
            {
                if (Equals(this.placeIndex, value)) return;

                this.placeIndex = value;

                if (this.PlaceIndex > 0) this.IsSendStats = true;
            }
        }

        private bool IsSendStats { get; set; }

        private List<StatsValuesClass> StatsList
        {
            get
            {
                return this.statsList;
            }
            set
            {
                if (Equals(this.statsList, value)) return;

                this.statsList = value;
                this.OnPropertyChanged("StatsList");
            }
        }

        public String FullCharacters
        {
            get
            {
                return this.fullCharacters;
            }
            private set
            {
                if (Equals(this.fullCharacters, value)) return;

                this.fullCharacters = value;
                this.OnPropertyChanged("FullCharacters");
            }
        }

        public String FullCharacters2
        {
            get
            {
                return this.fullCharacters2;
            }
            private set
            {
                if (Equals(this.fullCharacters2, value)) return;

                this.fullCharacters2 = value;
                this.OnPropertyChanged("FullCharacters2");
            }
        }

        public String MainCharacters
        {
            get
            {
                return this.mainCharacters;
            }
            private set
            {
                if (Equals(this.mainCharacters, value)) return;

                this.mainCharacters = value;
                this.OnPropertyChanged("MainCharacters");
            }
        }

        public string TranslateName
        {
            get
            {
                return this.translateName;
            }

            private set
            {
                if (this.translateName == value) return;

                this.translateName = value;
                this.OnPropertyChanged("TranslateName");
            }
        }

        public BitmapImage Icon
        {
            get
            {
                return this.icon;
            }

            private set
            {
                if (Equals(this.icon, value)) return;

                this.icon = value;
                this.OnPropertyChanged("Icon");
            }
        }

        public bool IsCraftItem
        {
            set
            {
                this.isCraftItem = value;
            }
        }

        public SolidColorBrush TranslateColor
        {
            get
            {
                return this.translateColor;
            }

            private set
            {
                if (Equals(this.translateColor, value)) return;

                this.translateColor = value;
                this.OnPropertyChanged("TranslateColor");
            }
        }

        public ObservableCollection<Visibility> ExchangeVisible
        {
            get
            {
                return this.exchangeVisible;
            }
            private set
            {
                if (Equals(this.exchangeVisible, value)) return;

                this.exchangeVisible = value;
                this.OnPropertyChanged("ExchangeVisible");
            }
        }

        public string CardTag
        {
            get
            {
                return this.cardTag;
            }
            private set
            {
                if (Equals(this.cardTag, value)) return;

                this.cardTag = value;
                this.OnPropertyChanged("CardTag");

                this.CardVisible = Visibility.Hidden;
            }
        }

            #endregion

            #region Items

        private DataRow item;
        private DataRow saveItem;
        private DataRow saveItem2;
        
        private BitmapImage icon;
        private string itemType;
        private string itemSpeed;
        private string itemLevel;
        private string itemLevelTag;
        private string itemSoul;
        private string itemExchange;
        private ObservableCollection<Visibility> exchangeVisible;

        private Visibility itemsSelectorVisible;
        private byte loadItemIndex;
        private Visibility cardVisible;
        private string cardTag;

        public byte LoadItemIndex
        {
            set
            {
                if (Equals(this.loadItemIndex, value)) return;

                this.loadItemIndex = value;
            }
        }

        public DataRow Item
        {
            get
            {
                return this.item;
            }
            set
            {
                if (Equals(this.item, value)) return;

                this.item = value;
                this.OnPropertyChanged("Item");
            }
        }

        public DataRow SaveItem
        {
            get
            {
                return this.saveItem;
            }
            set
            {
                if (Equals(this.saveItem, value)) return;
                this.saveItem = value;
            }
        }

        public DataRow SaveItem2
        {
            private get
            {
                return this.saveItem2;
            }
            set
            {
                if (Equals(this.saveItem2, value)) return;
                this.saveItem2 = value;
            }
        }
        
        public Visibility ItemsSelectorVisible
        {
            get
            {
                return this.itemsSelectorVisible;
            }
            private set
            {
                if (Equals(this.itemsSelectorVisible, value)) return;

                this.itemsSelectorVisible = value;
                this.OnPropertyChanged("ItemsSelectorVisible");
            }
        }
        
        public string ItemType
        {
            get
            {
                return this.itemType;
            }
            private set
            {
                if (Equals(this.itemType, value)) return;

                this.itemType = value;
                this.OnPropertyChanged("ItemType");
            }
        }

        public string ItemSpeed
        {
            get
            {
                return this.itemSpeed;
            }
            private set
            {
                if (Equals(this.itemSpeed, value)) return;

                this.itemSpeed = value;
                this.OnPropertyChanged("ItemSpeed");
            }
        }

        public string ItemLevel
        {
            get
            {
                return this.itemLevel;
            }
            private set
            {
                if (Equals(this.itemLevel, value)) return;

                this.itemLevel = value;
                this.OnPropertyChanged("ItemLevel");
            }
        }

        public string ItemLevelTag
        {
            get
            {
                return this.itemLevelTag;
            }
            private set
            {
                if (Equals(this.itemLevelTag, value)) return;

                this.itemLevelTag = value;
                this.OnPropertyChanged("ItemLevelTag");
            }
        }

        public string ItemSoul
        {
            get
            {
                return this.itemSoul;
            }
            private set
            {
                if (Equals(this.itemSoul, value)) return;

                this.itemSoul = value;
                this.OnPropertyChanged("ItemSoul");
            }
        }

        public string ItemExchange
        {
            get
            {
                return this.itemExchange;
            }
            private set
            {
                if (Equals(this.itemExchange, value)) return;

                this.itemExchange = value;
                this.OnPropertyChanged("ItemExchange");
            }
        }
        
            #endregion

            #region Armsfusion

        private Visibility armsfusionVisible;
        private Visibility armsfusionBonusVisible;
        private Visibility armsfusionManastonesVisible;
        private string armsfusionBonusCharacters;
        private ObservableCollection<ManaStone> armsfusionManastones;
        private string armsfusionManastoneText;
        private byte armsfusionManastonesMaxLevel;
        private SolidColorBrush armsfusionTitleColor;

        private DataRow ArmsfusionItem { get; set; }

        public Visibility ArmsfusionVisible
        {
            get
            {
                return this.armsfusionVisible;
            }
            private set
            {
                if (Equals(this.armsfusionVisible, value)) return;

                this.armsfusionVisible = value;
                this.OnPropertyChanged("ArmsfusionVisible");
            }
        }

        public Visibility ArmsfusionBonusVisible
        {
            get
            {
                return this.armsfusionBonusVisible;
            }
            private set
            {
                if (Equals(this.armsfusionBonusVisible, value)) return;

                this.armsfusionBonusVisible = value;
                this.OnPropertyChanged("ArmsfusionBonusVisible");
            }
        }

        public Visibility ArmsfusionManastonesVisible
        {
            get
            {
                return this.armsfusionManastonesVisible;
            }
            private set
            {
                if (Equals(this.armsfusionManastonesVisible, value)) return;

                this.armsfusionManastonesVisible = value;
                this.OnPropertyChanged("ArmsfusionManastonesVisible");
            }
        }

        public string ArmsfusionBonusCharacters
        {
            get
            {
                return this.armsfusionBonusCharacters;
            }
            private set
            {
                if (Equals(this.armsfusionBonusCharacters, value)) return;

                this.armsfusionBonusCharacters = value;
                this.OnPropertyChanged("ArmsfusionBonusCharacters");
            }
        }

        public bool IsArmsfusionItem { get; set; }

        public ObservableCollection<ManaStone> ArmsfusionManastones
        {
            get
            {
                return this.armsfusionManastones;
            }
            private set
            {
                if (Equals(this.armsfusionManastones, value)) return;

                this.armsfusionManastones = value;
                this.OnPropertyChanged("ArmsfusionManastones");
            }
        }

        public string ArmsfusionManastoneText
        {
            get
            {
                return this.armsfusionManastoneText;
            }
            set
            {
                if (Equals(this.armsfusionManastoneText, value)) return;

                this.armsfusionManastoneText = value;
                this.OnPropertyChanged("ArmsfusionManastoneText");
            }
        }

        public SolidColorBrush ArmsfusionTitleColor
        {
            get
            {
                return this.armsfusionTitleColor;
            }

            private set
            {
                if (Equals(this.armsfusionTitleColor, value)) return;

                this.armsfusionTitleColor = value;
                this.OnPropertyChanged("ArmsfusionTitleColor");
            }
        }

        public List<KeyValuePair<string, float>> ArmsfusionGodEnchantStats { get; set; }

        #endregion

            #region Manastones

        private Visibility manastonesVisible;
        private ObservableCollection<ManaStone> manastones;
        private string manastoneText;

        public byte ManastonesMaxLevel { get; set; }
        public string ManastoneText
        {
            get
            {
                return this.manastoneText;
            }
            set
            {
                if (Equals(this.manastoneText, value)) return;

                this.manastoneText = value;
                this.OnPropertyChanged("ManastoneText");
            }
        }

        public Visibility ManastonesVisible
        {
            get
            {
                return this.manastonesVisible;
            }
            private set
            {
                if (Equals(this.manastonesVisible, value)) return;

                this.manastonesVisible = value;
                this.OnPropertyChanged("ManastonesVisible");
            }
        }

        public ObservableCollection<ManaStone> Manastones
        {
            get
            {
                return this.manastones;
            }
            private set
            {
                if (Equals(this.manastones, value)) return;

                this.manastones = value;
                this.OnPropertyChanged("Manastones");
            }
        }
        
            #endregion

            #region Bonuses

        private Visibility bonusVisible;
        private String bonusCharacters;

        public Visibility BonusVisible
        {
            get
            {
                return this.bonusVisible;
            }
            private set
            {
                if (Equals(this.bonusVisible, value)) return;

                this.bonusVisible = value;
                this.OnPropertyChanged("BonusVisible");
            }
        }

        public string BonusCharacters
        {
            get
            {
                return this.bonusCharacters;
            }
            private set
            {
                if (Equals(this.bonusCharacters, value)) return;

                this.bonusCharacters = value;
                this.OnPropertyChanged("BonusCharacters");
            }
        }

            #endregion

            #region Enchant

        private Visibility enchantVisible;
        private string enchantLevelText;
        private byte enchant;
        private byte maximumEnchant;

        public string EnchantLevelText
        {
            get
            {
                return this.enchantLevelText;
            }
            private set
            {
                if (Equals(this.enchantLevelText, value)) return;

                this.enchantLevelText = value;
                this.OnPropertyChanged("EnchantLevelText");
            }
        }

        public byte Enchant
        {
            get
            {
                return this.enchant;
            }
            set
            {
                this.EnchantLevelText = String.Format("{0}  {1}/{2}", Resources.Enchant, value, this.MaximumEnchant);

                if (Equals(this.enchant, value)) return;

                this.enchant = value;
                this.OnPropertyChanged("Enchant");

                this.GetEnchantStats();

                this.ShowFullStatsTable();
            }
        }

        public Visibility EnchantVisible
        {
            get
            {
                return this.enchantVisible;
            }
            private set
            {
                if (Equals(this.enchantVisible, value)) return;

                this.enchantVisible = value;
                this.OnPropertyChanged("EnchantVisible");
            }
        }

        public byte MaximumEnchant
        {
            get
            {
                return this.maximumEnchant;
            }
            private set
            {
                if (Equals(this.maximumEnchant, value)) return;

                this.maximumEnchant = value;
                this.OnPropertyChanged("MaximumEnchant");
            }
        }

            #endregion

            #region Idian

        private Visibility idianVisible;
        private Idian idian;
        private byte idianMaxLevel;
        private string idianText;
        private String idianCharacters;

        public string IdianText
        {
            get
            {
                return this.idianText;
            }
            set
            {
                if (Equals(this.idianText, value)) return;

                this.idianText = value;
                this.OnPropertyChanged("IdianText");
            }
        }

        private Idian Idian
        {
            get
            {
                return this.idian;
            }
            set
            {
                if (Equals(this.idian, value)) return;

                this.idian = value;
                this.OnPropertyChanged("Idian");

                this.CreateIdianTable();
            }
        }

        public Visibility IdianVisible
        {
            get
            {
                return this.idianVisible;
            }
            private set
            {
                if (Equals(this.idianVisible, value)) return;

                this.idianVisible = value;
                this.OnPropertyChanged("IdianVisible");
            }
        }

        public string IdianCharacters
        {
            get
            {
                return this.idianCharacters;
            }
            private set
            {
                if (Equals(this.idianCharacters, value)) return;

                this.idianCharacters = value;
                this.OnPropertyChanged("IdianCharacters");
            }
        }

            #endregion

            #region God Enchant

        private Visibility godEnchantVisible;
        private string godEnchantCharactersLevel1;
        private string godEnchantCharactersLevel2;
        private string godEnchantText;
        private byte godEnchantLevel;
        private byte godEnchantMaxLevel;
        private float[] godEnchantLevelsOpacity;

        public byte GodEnchantLevel
        {
            get
            {
                return this.godEnchantLevel;
            }
            set
            {
                this.GodEnchantText = string.Format(Resources.GodEnchant_Level, value);

                if (Equals(this.godEnchantLevel, value)) return;
                this.godEnchantLevel = value;

                this.OnPropertyChanged("GodEnchantLevel");

                this.SetGodEnchantCharactersOpacity();
                this.GetGodEnchantStats();
            }
        }

        public string GodEnchantText
        {
            get
            {
                return this.godEnchantText;
            }
            set
            {
                if (Equals(this.godEnchantText, value)) return;

                this.godEnchantText = value;
                this.OnPropertyChanged("GodEnchantText");
            }
        }

        public byte GodEnchantMaxLevel
        {
            get
            {
                return this.godEnchantMaxLevel;
            }
            private set
            {
                if (Equals(this.godEnchantMaxLevel, value)) return;
                this.godEnchantMaxLevel = value;

                this.OnPropertyChanged("GodEnchantMaxLevel");
            }
        }

        public Visibility GodEnchantVisible
        {
            get
            {
                return this.godEnchantVisible;
            }
            private set
            {
                if (Equals(this.godEnchantVisible, value)) return;

                this.godEnchantVisible = value;
                this.OnPropertyChanged("GodEnchantVisible");
            }
        }

        public string GodEnchantCharactersLevel1
        {
            get
            {
                return this.godEnchantCharactersLevel1;
            }
            set
            {
                if (Equals(this.godEnchantCharactersLevel1, value)) return;

                this.godEnchantCharactersLevel1 = value;
                this.OnPropertyChanged("godEnchantCharactersLevel1");
            }
        }

        public string GodEnchantCharactersLevel2
        {
            get
            {
                return this.godEnchantCharactersLevel2;
            }
            set
            {
                if (Equals(this.godEnchantCharactersLevel2, value)) return;

                this.godEnchantCharactersLevel2 = value;
                this.OnPropertyChanged("godEnchantCharactersLevel2");
            }
        }

        public float[] GodEnchantLevelsOpacity
        {
            get
            {
                return this.godEnchantLevelsOpacity;
            }
            set
            {
                if (Equals(value, this.godEnchantLevelsOpacity)) return;
                this.godEnchantLevelsOpacity = value;

                this.OnPropertyChanged("GodEnchantLevelsOpacity");
            }
        }

        public List<KeyValuePair<string, float>> GodEnchantStats { get; set; }

        #endregion

            #region ItemSet

        private Visibility itemSetVisible;
        private string itemSetText;
        private String itemSetCharacters;
        private ItemSet itemSet;

        public Visibility ItemSetVisible
        {
            get
            {
                return this.itemSetVisible;
            }
            private set
            {
                if (Equals(this.itemSetVisible, value)) return;

                this.itemSetVisible = value;
                this.OnPropertyChanged("ItemSetVisible");
            }
        }

        public string ItemSetText
        {
            get
            {
                return this.itemSetText;
            }
            set
            {
                if (Equals(this.itemSetText, value)) return;

                this.itemSetText = value;
                this.OnPropertyChanged("ItemSetText");
            }
        }

        public string ItemSetCharacters
        {
            get
            {
                return this.itemSetCharacters;
            }
            private set
            {
                if (Equals(this.itemSetCharacters, value)) return;

                this.itemSetCharacters = value;
                this.OnPropertyChanged("ItemSetCharacters");
            }
        }

        public ItemSet ItemSet
        {
            get
            {
                return this.itemSet;
            }
            set
            {
                if (Equals(this.itemSet, value)) return;

                this.itemSet = value;
            }
        }

            #endregion

            #region Coins

        private string extraCurrencyIcon;
        private string extraCurrencyName;
        private ObservableCollection<DataRow> coins;
        private List<Visibility> abyssPointsVisible;

        public ObservableCollection<DataRow> Coins
        {
            get
            {
                return this.coins;
            }
            private set
            {
                if (Equals(this.coins, value)) return;

                this.coins = value;
                this.OnPropertyChanged("Coins");
            }
        }

        public string ExtraCurrencyIcon
        {
            get
            {
                return this.extraCurrencyIcon;
            }
            set
            {
                if (Equals(this.extraCurrencyIcon, value)) return;
                this.extraCurrencyIcon = value;

                this.OnPropertyChanged("ExtraCurrencyIcon");
            }
        }

        public string ExtraCurrencyName
        {
            get
            {
                return this.extraCurrencyName;
            }
            set
            {
                if (Equals(this.extraCurrencyName, value)) return;
                this.extraCurrencyName = value;

                this.OnPropertyChanged("ExtraCurrencyName");
            }
        }

        public List<Visibility> AbyssPointsVisible
        {
            get
            {
                return this.abyssPointsVisible;
            }
            set
            {
                if (Equals(this.abyssPointsVisible, value)) return;
                this.abyssPointsVisible = value;

                this.OnPropertyChanged("AbyssPointsVisible");
            }
        }

            #endregion

            #region Random Bonus

        private Visibility randomBonusVisible;
        private string randomBonusText;
        private string randomBonusCharacters;
        private RandomBonus randomBonus;

        public Visibility RandomBonusVisible
        {
            get
            {
                return this.randomBonusVisible;
            }
            private set
            {
                if (Equals(this.randomBonusVisible, value)) return;

                this.randomBonusVisible = value;
                this.OnPropertyChanged("RandomBonusVisible");
            }
        }

        public string RandomBonusText
        {
            get
            {
                return this.randomBonusText;
            }
            set
            {
                if (Equals(this.randomBonusText, value)) return;

                this.randomBonusText = value;
                this.OnPropertyChanged("RandomBonusText");
            }
        }

        public string RandomBonusCharacters
        {
            get
            {
                return this.randomBonusCharacters;
            }
            set
            {
                if (Equals(this.randomBonusCharacters, value)) return;

                this.randomBonusCharacters = value;
                this.OnPropertyChanged("randomBonusCharacters");
            }
        }

        private RandomBonus RandomBonus
        {
            get
            {
                return this.randomBonus;
            }
            set
            {
                if (Equals(this.randomBonus, value)) return;
                this.randomBonus = value;

                this.CreateRandomBonusTable();
            }
        }

            #endregion

        #endregion

        #region Commands

        public RelayCommand<string> ChangeSelectionIndexCommand { get; private set; }
        public RelayCommand<string> OpenManastoneCommand { get; private set; }
        public RelayCommand<Button> DeleteManastoneCommand { get; private set; }
        public RelayCommand<Button> CopyManastoneCommand { get; private set; }
        public RelayCommand<string> PageSelectCommand { get; private set; }
        public RelayCommand OpenIdianCommand { get; private set; }
        public RelayCommand OpenRandomBonusCommand { get; private set; }
        public RelayCommand<string> OpenArmsfusionManastoneCommand { get; private set; }
        public RelayCommand<Button> CopyArmsfusionManastoneCommand { get; private set; }
        public RelayCommand<Button> DeleteArmsfusionManastoneCommand { get; private set; }
        #endregion

        #region General Code

        private void WireCommands()
        {
            this.ChangeSelectionIndexCommand = new RelayCommand<string>(this.ChangeSelectionIndex) { IsEnabled = true };
            this.OpenManastoneCommand = new RelayCommand<string>(this.OpenManastone) { IsEnabled = true };
            this.DeleteManastoneCommand = new RelayCommand<Button>(this.DeleteManastone) { IsEnabled = true };
            this.CopyManastoneCommand = new RelayCommand<Button>(this.CopyManastone) { IsEnabled = true };
            this.PageSelectCommand = new RelayCommand<string>(this.PageSelect) { IsEnabled = true };
            this.OpenIdianCommand = new RelayCommand(this.OpenIdian) { IsEnabled = true };
            this.OpenRandomBonusCommand = new RelayCommand(this.OpenRandomBonus) { IsEnabled = true };
            this.OpenArmsfusionManastoneCommand = new RelayCommand<string>(this.OpenArmsfusionManastone) { IsEnabled = true };
            this.DeleteArmsfusionManastoneCommand = new RelayCommand<Button>(this.DeleteArmsfusionManastone) { IsEnabled = true };
            this.CopyArmsfusionManastoneCommand = new RelayCommand<Button>(this.CopyArmsfusionManastone) { IsEnabled = true };
        }

        public Card3ViewModel()
        {
            this.WireCommands();

            this.CardVisible = Visibility.Collapsed;
            this.PagesVisible = new ObservableCollection<Visibility>()
                           {
                               Visibility.Visible,
                               Visibility.Collapsed,
                               Visibility.Collapsed
                           };
            this.FirstPageChecked = true;
            this.Item = null;
            this.SaveItem = null;
            this.SaveItem2 = null;
            this.IsArmsfusionItem = false;

            Mediator.Instance.Register(o => this.GetItemSet((ItemSets)o), Messages.ItemSetSend);
        }

        public Card3ViewModel(byte placeIndex)
            : this()
        {
            this.PlaceIndex = placeIndex;
        }

        public void LoadItem(DataRow row, bool isExtended = false)
        {
            if (!isExtended)
            {
                this.Item = row;
                this.saveItem = row;
            }
            else
            {
                this.SaveItem2 = row;
            }
            
        }

        private bool CanVisible()
        {
            if (this.Item == null)
            {
                this.CardVisible = Visibility.Collapsed;
                return false;
            }

            this.CardVisible = Visibility.Visible;
            return true;
        }

        private void PageSelect(string pageIndex)
        {
            switch (pageIndex)
            {
                case "1":
                    this.PagesVisible[0] = Visibility.Visible;
                    this.PagesVisible[1] = Visibility.Collapsed;
                    this.PagesVisible[2] = Visibility.Collapsed;
                    break;
                case "2":
                    this.PagesVisible[0] = Visibility.Collapsed;
                    this.PagesVisible[1] = Visibility.Visible;
                    this.PagesVisible[2] = Visibility.Collapsed;
                    break;
                case "3":
                    this.PagesVisible[0] = Visibility.Collapsed;
                    this.PagesVisible[1] = Visibility.Collapsed;
                    this.PagesVisible[2] = Visibility.Visible;
                    break;
            }
        }

        internal void LoadCard()
        {
            if (this.Item == null)
            {
                this.CardVisible = Visibility.Collapsed;
                return;
            }
            
            if (!this.CanVisible()) return;

            this.SetItemsSelector();
            this.ResetAndFormCard();

            this.CardIsLoaded = true;
        }

        private void ChangeSelectionIndex(string index)
        {
            this.Item = index == "0" ? this.saveItem : this.saveItem2;
            this.ResetAndFormCard();
        }

        private void ResetAndFormCard()
        {
            this.SetMaxEnchantLevel();
            this.Enchant = 0;
            this.GodEnchantLevel = 0;
            this.idianMaxLevel = this.GetIdianMaxLevel();

            this.StatsList = new List<StatsValuesClass>();
            this.Idian = new Idian();
            this.ItemSet = null;

            this.GenerateCard();
        }

        private void SetItemsSelector()
        {
            if (this.SaveItem2 == null)
            {
                this.ItemsSelectorVisible = Visibility.Collapsed;
                return;
            }

            this.ItemsSelectorVisible = Visibility.Visible;
        }

        private void GenerateCard()
        {
            this.GenerateTopOfCard();

            this.AdditionalStats();
            this.SelectGroupOfMainStats();
            this.OtherStats();
        }

        private void AdditionalStats()
        {
            this.CreateEnchantTable();
            this.CreateManaStonesTable();
            this.CreateIdianTable();
            this.CreateRandomBonusTable();
            this.SetGodEnchant();
            this.GetItemSet(null);
            this.SetArmsfusion();
        }

        private void OtherStats()
        {
            this.CreateCoinsTable();
        }

        private void UpdateEnchantList(
            char valueId,
            string stat,
            Single value,
            Single value2 = 0,
            EnchantStates state = EnchantStates.Value,
            string unit = "",
            string tips = "")
        {
            if (string.IsNullOrEmpty(stat)) return;

            StatsValuesClass statsValues = this.StatsList.Find(s => s.Stat == stat);
            if (statsValues == null)
            {
                statsValues = new StatsValuesClass(valueId, stat, value, value2, unit);
                this.StatsList.Add(statsValues);
            }
            else
            {
                statsValues.UpdateStatValue(valueId, value, value2, state, unit);
            }

            if (!string.IsNullOrEmpty(tips)) statsValues.Tips = tips;

            if (this.PlaceIndex > 0 && this.IsSendStats) this.SendStat(statsValues);
        }

        public void SendAllStats()
        {
            if (this.PlaceIndex == 0 || this.PlaceIndex == 16 || !this.IsSendStats) return;

            if (this.StatsList == null || this.StatsList.Count == 0)
            {
                Mediator.Instance.NotifyColleagues(Messages.CardStatsNullSend, this.PlaceIndex);
            }
            else
            {
                foreach (StatsValuesClass stat in this.StatsList)
                {
                    this.SendStat(stat);
                }
            }
        }

        private void SendStat(StatsValuesClass statsValues)
        {
            if (this.PlaceIndex == 0 || this.PlaceIndex == 16) return;
            
            KeyValuePair<byte, StatsValuesClass> statsOut = new KeyValuePair<byte, StatsValuesClass>(this.PlaceIndex, statsValues);
            Mediator.Instance.NotifyColleagues(Messages.CardStatsSend, statsOut);
        }

        public XElement GetCardElementForSaveToFile()
        {
            XElement xCard = new XElement("Place");

            xCard.Add(new XAttribute("Index", this.PlaceIndex));
            if (this.Item != null) xCard.Add(new XAttribute("Item", this.Item["Name"].ToString()));
            if (this.Enchant > 0) xCard.Add(new XAttribute("Enchant", this.Enchant));
            if (this.Idian != null && !String.IsNullOrEmpty(this.Idian.Name)) xCard.Add(new XAttribute("Idian", this.Idian.Name));
            if (this.RandomBonus != null) xCard.Add(new XAttribute("RandomBonus", this.RandomBonus.Id));
            if (this.GodEnchantLevel > 0) xCard.Add(new XAttribute("GodEnchant", this.GodEnchantLevel));

            if (this.Manastones != null)
            {
                foreach (ManaStone stone in this.Manastones)
                {
                    XElement xStone = new XElement("Manastone");
                    xStone.Add(new XAttribute("Index", stone.Index));
                    if (stone.Row != null) xStone.Add(new XAttribute("Name", stone.Row["Name"].ToString()));
                    xCard.Add(xStone);
                }
            }

            return xCard;
        }

        #endregion

        #region TopOfCard Code

        private void GenerateTopOfCard()
        {
            this.TranslateName = this.Item["translate" + DataModel.EngFix].ToString();

            string iconName = this.Item["icon_name"].ToString().Trim() + ".png";
            BitmapImage tIcon = new BitmapImage();
            Uri uri;
            if (File.Exists(DataModel.IconsDirectory + iconName))
            {
                Uri.TryCreate(DataModel.IconsDirectory + iconName, UriKind.RelativeOrAbsolute, out uri);
            }
            else
            {
                uri = new Uri("pack://application:,,,/CAION2;component/UI2/IconSlot.png", UriKind.Absolute);
            }
            tIcon.BeginInit();
            tIcon.UriSource = uri;
            tIcon.EndInit();
            this.Icon = tIcon;

            ItemTypeColorConverter itc = new ItemTypeColorConverter();
            this.TranslateColor = (SolidColorBrush)itc.Convert(this.Item["quality"], null, null, null);

            this.ItemType = GetItemType(this.Item["name"].ToString())
                       + GetItemRank(this.Item["item_type"].ToString());
            this.ItemSpeed = this.GetWeaponSpeedText();

            this.ItemLevel = this.GetLevelNeedText();
            this.ItemSoul = this.Item["soul_bind"].ToString() == "TRUE" ? Resources.CardPutSoul : "";

            this.ItemExchange = this.GetExchangeInfo();
            this.GetAdditionalExchangeInfo();
        }

        private static string GetItemType(string value)
        {
            try
            {
                return ClassItem.Types.FirstOrDefault(localType => value.ToUpper().Contains(localType.Key)).Value;
            }
            catch
            {
                return "";
            }
        }

        private static string GetItemRank(string value)
        {
            try
            {
                string rank = ClassItem.Ranks.FirstOrDefault(localType => value.ToUpper().Contains(localType.Key)).Value;
                if (!string.IsNullOrEmpty(rank)) rank = " (" + rank + ")";
                return rank;
            }
            catch
            {
                return "";
            }
        }

        private string GetWeaponSpeedText()
        {
            if (!this.Item.Table.Columns.Contains("weapon_type")) return "";

            if (String.IsNullOrEmpty(this.Item["weapon_type"].ToString())) return "";

            Int16 speed = Convert.ToInt16(this.Item["attack_delay"]);
            Byte hitCount = Convert.ToByte(this.Item["hit_count"]);

            string result;

            switch (speed)
            {
                case 1200:
                    result = String.Format(Resources.CardWeaponSpeed1, hitCount);
                    break;
                case 1400:
                case 1500:
                    result = String.Format(Resources.CardWeaponSpeed2, hitCount);
                    break;
                case 2000:
                case 2200:
                    result = String.Format(Resources.CardWeaponSpeed3, hitCount);
                    break;
                case 2400:
                case 2800:
                    result = String.Format(Resources.CardWeaponSpeed4, hitCount);
                    break;
                default:
                    result = String.Format(Resources.CardWeaponSpeed0, hitCount);
                    break;
            }

            switch (this.Item["attack_type"].ToString())
            {
                case "magical_water":
                    result += "\n(" + Resources.Stats_AttackType_magical_water + ")";
                    break;
                case "magical_fire":
                    result += "\n(" + Resources.Stats_AttackType_magical_fire + ")";
                    break;
            }

            return result;
        }

        private string GetLevelNeedText()
        {
            Byte level = Convert.ToByte(this.Item["level"].ToString());
            this.ItemLevelTag = "";

            if (this.Item.Table.Columns["warrior"] == null) return String.Format(Resources.CardLevel, level);

            List<string> avaClasses = new List<string>();
            if (this.Item["warrior"].ToString() != "0") avaClasses.Add(Resources.Class_Warrior);
            if (this.Item["scout"].ToString() != "0") avaClasses.Add(Resources.Class_Scout);
            if (this.Item["mage"].ToString() != "0") avaClasses.Add(Resources.Class_Mage);
            if (this.Item["cleric"].ToString() != "0") avaClasses.Add(Resources.Class_Cleric);
            if (this.Item["engineer"].ToString() != "0") avaClasses.Add(Resources.Class_Engineer);
            if (this.Item["artist"].ToString() != "0") avaClasses.Add(Resources.Class_Artist);

            if (this.Item["fighter"].ToString() != "0") avaClasses.Add(Resources.Class_Fighter);
            if (this.Item["knight"].ToString() != "0") avaClasses.Add(Resources.Class_Knight);

            if (this.Item["assassin"].ToString() != "0") avaClasses.Add(Resources.Class_Assassin);
            if (this.Item["ranger"].ToString() != "0") avaClasses.Add(Resources.Class_Ranger);

            if (this.Item["wizard"].ToString() != "0") avaClasses.Add(Resources.Class_Wizard);
            if (this.Item["elementalist"].ToString() != "0") avaClasses.Add(Resources.Class_Elementalist);

            if (this.Item["chanter"].ToString() != "0") avaClasses.Add(Resources.Class_Chanter);
            if (this.Item["priest"].ToString() != "0") avaClasses.Add(Resources.Class_Priest);

            if (this.Item["gunner"].ToString() != "0") avaClasses.Add(Resources.Class_Gunner);
            if (this.Item["bard"].ToString() != "0") avaClasses.Add(Resources.Class_Bard);
            //if (Items[_currentItemIndex]["rider"].ToString() != "0") avaClasses.Add(Resources.CardRider);


            if (avaClasses.Count < 4) this.ItemLevelTag = "1";

            if (avaClasses.Count > 3) return String.Format(Resources.CardLevel, level);


            if (avaClasses.Count == 3)
            {
                if (avaClasses.Contains(Resources.Class_Warrior)) return String.Format(Resources.CardLevelUp, Resources.Class_Warrior, level);

                if (avaClasses.Contains(Resources.Class_Scout)) return String.Format(Resources.CardLevelUp, Resources.Class_Scout, level);

                if (avaClasses.Contains(Resources.Class_Mage)) return String.Format(Resources.CardLevelUp, Resources.Class_Mage, level);

                if (avaClasses.Contains(Resources.Class_Cleric)) return String.Format(Resources.CardLevelUp, Resources.Class_Cleric, level);
            }

            if (avaClasses.Count == 2)
            {
                if (avaClasses.Contains(Resources.Class_Engineer)) return String.Format(Resources.CardLevelUp, Resources.Class_Engineer, level);

                if (avaClasses.Contains(Resources.Class_Artist)) return String.Format(Resources.CardLevelUp, Resources.Class_Artist, level);
            }

            if (avaClasses.Count == 1)
            {
                if (avaClasses.Contains(Resources.Class_Fighter)) return String.Format(Resources.CardLevelUp, Resources.Class_Fighter, level);

                if (avaClasses.Contains(Resources.Class_Knight)) return String.Format(Resources.CardLevelUp, Resources.Class_Knight, level);

                if (avaClasses.Contains(Resources.Class_Assassin)) return String.Format(Resources.CardLevelUp, Resources.Class_Assassin, level);

                if (avaClasses.Contains(Resources.Class_Ranger)) return String.Format(Resources.CardLevelUp, Resources.Class_Ranger, level);

                if (avaClasses.Contains(Resources.Class_Wizard)) return String.Format(Resources.CardLevelUp, Resources.Class_Wizard, level);

                if (avaClasses.Contains(Resources.Class_Elementalist)) return String.Format(Resources.CardLevelUp, Resources.Class_Elementalist, level);

                if (avaClasses.Contains(Resources.Class_Chanter)) return String.Format(Resources.CardLevelUp, Resources.Class_Chanter, level);

                if (avaClasses.Contains(Resources.Class_Priest)) return String.Format(Resources.CardLevelUp, Resources.Class_Priest, level);

                if (avaClasses.Contains(Resources.Class_Gunner)) return String.Format(Resources.CardLevelUp, Resources.Class_Gunner, level);

                if (avaClasses.Contains(Resources.Class_Bard)) return String.Format(Resources.CardLevelUp, Resources.Class_Bard, level);
            }

            return String.Format(Resources.CardLevel, level);
        }

        private string GetExchangeInfo()
        {
            return this.Item["can_exchange"].ToString() == "FALSE" ? Resources.CardCantExchange : "";
        }

        private void GetAdditionalExchangeInfo()
        {
            this.ExchangeVisible = new ObservableCollection<Visibility>
                              {
                                  this.Item["can_sell_to_npc"]
                                      .ToString() == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item[
                                      "can_deposit_to_character_warehouse"]
                                      .ToString() == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item[
                                      "can_deposit_to_account_warehouse"].ToString(
                                          ) == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item[
                                      "can_deposit_to_guild_warehouse"].ToString()
                                  == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item["can_proc_enchant"]
                                      .ToString() == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item["cannot_extraction"]
                                      .ToString() == "TRUE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item["can_ap_extraction"]
                                      .ToString() == "TRUE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item["extract_skin_type"]
                                      .ToString() == "2"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  this.Item["cannot_changeskin"]
                                      .ToString() == "1"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed
                              };


        }

        #endregion

        #region Stats Code

        private void SelectGroupOfMainStats()
        {
            if (this.Item.Table.Columns.Contains("weapon_type")
                && this.Item["weapon_type"].ToString() != "")
            {
                this.UpdateStatsFromWeapon();
                this.UpdateStatsFromBonus();
                
                this.ShowMainStatsWeaponTable();
                this.ShowFullStatsTable();
            }
            else if (this.Item.Table.Columns.Contains("armor_type")
                     && !string.IsNullOrEmpty(this.Item["armor_type"].ToString())
                     && this.Item["armor_type"].ToString() != "no_armor"
                     && this.Item["equipment_slots"].ToString() != "wing")
            {
                this.UpdateStatsFromArmor();
                this.UpdateStatsFromBonus();
                
                this.ShowMainStatsArmorTable();
                this.ShowFullStatsTable();
            }
            else if (this.Item["name"].ToString().Substring(0, 6) == "shield"
                     && this.Item["equipment_slots"].ToString() == "sub")
            {
                this.UpdateStatsFromShield();
                this.UpdateStatsFromBonus();
                
                this.ShowMainStatsShieldTable();
                this.ShowFullStatsTable();
            }
            else if (this.Item["equipment_slots"].ToString() == "head"
                     || this.Item["equipment_slots"].ToString() == "wing")
            {
                this.UpdateStatsFromArmor();
                this.UpdateStatsFromBonus();

                this.ShowMainStatsArmorTable();
                this.ShowFullStatsTable();
            }
            else if (this.Item["activation_skill"].ToString().Contains("food")
                     || this.Item["name"].ToString().Contains("potion_")
                     || this.Item["name"].ToString().Contains("remedy_"))
            {
                this.UpdateAndShowStatsFromFood();
            }
            else if (JewelMarks.Contains(this.Item["equipment_slots"].ToString()))
            {
                this.UpdateStatsFromJewel();
                this.UpdateStatsFromBonus();

                this.ShowMainStatsJewelsTable();
                this.ShowFullStatsTable();
            }
            else
            {
                this.FullCharacters = "";
                this.FullCharacters2 = "";
                this.MainCharacters = "";
            }

            this.ShowBonusStatsTable();
        }

        private void UpdateStatsFromWeapon()
        {           
            this.UpdateEnchantList(
                'x',
                "phyattack",
                (int)this.Item["min_damage"],
                (int)this.Item["max_damage"],
                tips: this.Item["weapon_type"].ToString());


            if (this.Item["magical_skill_boost"].ToString() != "0")
            {
                this.UpdateEnchantList('x', "magicalskillboost", (int)this.Item["magical_skill_boost"]);
            }

            this.UpdateEnchantList('x', "attackdelay", Convert.ToSingle(this.Item["attack_delay"]) / 1000);
            
            if (this.Item["hit_accuracy"].ToString() != "0") this.UpdateEnchantList('x', "hitaccuracy", (int)this.Item["hit_accuracy"]);
            
            if (this.Item["critical"].ToString() != "0") this.UpdateEnchantList('x', "critical", (int)this.Item["critical"]);

            if (this.Item["parry"].ToString() != "0") this.UpdateEnchantList('x', "parry", (int)this.Item["parry"]);

            if (this.Item["magical_hit_accuracy"].ToString() != "0") this.UpdateEnchantList('x', "magicalhitaccuracy", (int)this.Item["magical_hit_accuracy"]);
        }

        private void UpdateStatsFromArmor()
        {
            if (this.Item.Table.Columns.Contains("physical_defend")
                && !DBNull.Value.Equals(this.Item["physical_defend"])
                && Convert.ToUInt32(this.Item["physical_defend"]) != 0) this.UpdateEnchantList('x', "physicaldefend", (int)this.Item["physical_defend"]);

            if (this.Item.Table.Columns.Contains("magical_skill_boost_resist")
                && !string.IsNullOrEmpty(this.Item["magical_skill_boost_resist"].ToString()))
                this.UpdateEnchantList(
                    'x',
                    "magicalskillboostresist",
                    (int)this.Item["magical_skill_boost_resist"]);

            if (this.Item.Table.Columns.Contains("magical_resist")
                && !DBNull.Value.Equals(this.Item["magical_resist"])
                && Convert.ToUInt32(this.Item["magical_resist"]) != 0) this.UpdateEnchantList('x', "magicalresist", (int)this.Item["magical_resist"]);

            if (this.Item.Table.Columns.Contains("dodge")
                && !DBNull.Value.Equals(this.Item["dodge"])
                && Convert.ToUInt32(this.Item["dodge"]) != 0) this.UpdateEnchantList('x', "dodge", (int)this.Item["dodge"]);
        }

        private void UpdateStatsFromShield()
        {
            if (Convert.ToUInt32(this.Item["block"]) != 0) this.UpdateEnchantList('x', "block", (int)this.Item["block"]);

            if (Convert.ToUInt32(this.Item["damage_reduce"]) != 0) this.UpdateEnchantList('x', "damagereduce", (int)this.Item["damage_reduce"]);
        }

        private void UpdateAndShowStatsFromFood()
        {
            Dictionary<string, string> fStats = new Dictionary<string, string>();

            DataRow result = DataModel.GetRowAtName(
                "Foods",
                this.Item["name"].ToString(),
                "translate" + DataModel.EngFix);

            fStats.Add(result["translate"].ToString(), "");

            this.ShowMainStatsFoodTable(fStats, false);
        }

        private void UpdateStatsFromJewel()
        {
            if (Convert.ToUInt32(this.Item["magical_resist"]) != 0) this.UpdateEnchantList('x', "magicalresist", (int)this.Item["magical_resist"]);

            if (!string.IsNullOrEmpty(this.Item["magical_skill_boost_resist"].ToString()))
                this.UpdateEnchantList(
                    'x',
                    "magicalskillboostresist",
                    (int)this.Item["magical_skill_boost_resist"]);
        }

        private void ShowFullStatsTable()
        {
            this.FullCharacters = "";
            this.FullCharacters2 = "";

            if (this.StatsList == null || this.StatsList.Count == 0) return;

            foreach (StatsValuesClass stat in this.StatsList.Where(stat => Math.Abs(stat.BasicValue + stat.Sum()) > 0))
            {
                this.FullCharacters += String.Format("{0}\n", stat.Translate);
                this.FullCharacters2 += String.Format("{0}{1}\n", stat.BasicValueText(), stat.SumValueText());
            }
        }

        private void ShowMainStatsWeaponTable()
        {
            this.MainCharacters = "";

            if (this.StatsList == null || this.StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();

            StatsValuesClass aStat = this.StatsList.Find(s => s.Stat == "phyattack");
            this.MainCharacters = String.Format(
                "{0,-20}[color=" + AppearanceManager.Current.AccentColor + "] {1}[/color]\n",
                aStat.Translate,
                aStat.BasicValueText());

            aStat = this.StatsList.Find(s => s.Stat == "magicalskillboost");
            if (aStat != null)
            {
                this.MainCharacters += converter.Convert(new KeyValuePair<string, float>(aStat.Translate, aStat.BasicValue),
                                                   null,
                                                   null,
                                                   null) + "\n";
            }


            List<string> mainStats = new List<string>
                                     {
                                         "attackdelay",
                                         "hitaccuracy",
                                         "critical",
                                         "parry",
                                         "magicalhitaccuracy"
                                     };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in this.StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                this.MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                   null,
                                                   null,
                                                   null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowMainStatsArmorTable()
        {
            this.MainCharacters = "";

            if (this.StatsList == null || this.StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            List<string> mainStats = new List<string>
                                     {
                                         "physicaldefend",
                                         "magicalskillboostresist",
                                         "magicalresist",
                                         "dodge"
                                     };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in this.StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                this.MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                    null,
                                                    null,
                                                    null) + caret;

                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowMainStatsShieldTable()
        {
            this.MainCharacters = "";

            if (this.StatsList == null || this.StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            List<string> mainStats = new List<string> { "block", "damagereduce" };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in this.StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                this.MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                    null,
                                                    null,
                                                    null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowMainStatsFoodTable(Dictionary<string, string> fStats, bool isShape)
        {
            this.MainCharacters = "";
            this.FullCharacters = "";
            this.FullCharacters2 = "";

            if (fStats == null || fStats.Count == 0) return;

            foreach (KeyValuePair<string, string> stat in fStats)
            {
                if (isShape)
                {
                    this.MainCharacters += stat.Key + "\n" + stat.Value;
                }
                else
                {
                    this.MainCharacters += stat.Key + " " + stat.Value + "\n";
                }
            }

            this.FullCharacters = this.MainCharacters;
        }

        private void ShowMainStatsJewelsTable()
        {
            this.MainCharacters = "";

            if (this.StatsList == null || this.StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            List<string> mainStats = new List<string> { "magicalresist", "magicalskillboostresist" };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in this.StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                this.MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                    null,
                                                    null,
                                                    null) + caret;

                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowBonusStatsTable()
        {
            this.BonusCharacters = "";

            if (this.StatsList == null || this.StatsList.Count == 0) return;

            BonusTextConverter converter = new BonusTextConverter();

            int i = 0;
            string caret = "\t  ";
            foreach (StatsValuesClass stat in this.StatsList.Where(stat => Math.Abs(stat.BonusValue) > 0))
            {
                string[] signs = new string[2];
                if (stat.BonusValue < 0)
                {
                    signs[0] = "";
                }
                else
                {
                    signs[0] = "+";
                }

                if (stat.Unit.Length > 0)
                {
                    signs[1] = stat.Unit;
                }
                else
                {
                    signs[1] = "";
                }
                

                this.BonusCharacters += converter.Convert(
                    new KeyValuePair<string, float>(stat.Translate, stat.BonusValue),
                    null,
                    signs,
                    null) + caret;

                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        #endregion

        #region Enchantment Code

        private void CreateEnchantTable()
        {
            if (this.MaximumEnchant == 0 || this.IsArmsfusionItem)
            {
                this.Enchant = 0;
                this.EnchantVisible = Visibility.Collapsed;
            }
            else
            {
                this.EnchantVisible = Enum.IsDefined(
                    typeof(ClassEnchantment.EnchantSlots),
                    this.Item["equipment_slots"].ToString())
                    ? Visibility.Visible
                    : Visibility.Collapsed;
            }
        }

        private void SetMaxEnchantLevel()
        {
            if (!this.Item.Table.Columns.Contains("max_enchant_value"))
            {
                this.MaximumEnchant = 0;
            }
            else
            {
                this.MaximumEnchant = this.Item["max_enchant_value"].ToString() != ""
                    ? Convert.ToByte(this.Item["max_enchant_value"])
                    : Convert.ToByte(0);
            }
        }

        #region EnchantmentKoeffs

        private int GetEnchantmentHPKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enKoeff = 0;

            switch (this.Item["armor_type"].ToString())
            {
                case "plate":
                    enKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].Hp;
                    break;
                case "chain":
                    enKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].Hp;
                    break;
                case "leather":
                    enKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].Hp;
                    break;
                case "robe":
                    enKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].Hp;
                    break;
            }

            return enKoeff * this.Enchant;
        }

        private int GetEnchantmentMagicalBlockKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enKoeff = 0;

            switch (this.Item["armor_type"].ToString())
            {
                case "plate":
                    enKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].MagicalBlock;
                    break;
                case "chain":
                    enKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].MagicalBlock;
                    break;
                case "leather":
                    enKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].MagicalBlock;
                    break;
                case "robe":
                    enKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].MagicalBlock;
                    break;
            }

            return enKoeff * this.Enchant;
        }

        private int GetEnchantmentDefenceKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enKoeff = 0;

            switch (this.Item["armor_type"].ToString())
            {
                case "plate":
                    enKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].PhysicalDefend;
                    break;
                case "chain":
                    enKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].PhysicalDefend;
                    break;
                case "leather":
                    enKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].PhysicalDefend;
                    break;
                case "robe":
                    enKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].PhysicalDefend;
                    break;
            }

            return enKoeff * this.Enchant;
        }

        private int GetEnchantmentDefenceResistKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enchantKoeff = 0;

            switch (this.Item["armor_type"].ToString())
            {
                case "plate":
                    enchantKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
                case "chain":
                    enchantKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
                case "leather":
                    enchantKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
                case "robe":
                    enchantKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
            }

            return enchantKoeff * this.Enchant;
        }

        private int GetEnchantmentAttackKoeff()
        {
            if (String.IsNullOrEmpty(this.Item["weapon_type"].ToString())) return 0;

            sbyte enKoeff =
                ClassEnchantment.WeaponEnchant[this.Item["weapon_type"].ToString()].MainHandAttack;
            return enKoeff * this.Enchant;
        }

        private int GetEnchantmentMagicBoostKoeff()
        {
            if (String.IsNullOrEmpty(this.Item["weapon_type"].ToString())) return 0;

            sbyte enKoeff =
                ClassEnchantment.WeaponEnchant[this.Item["weapon_type"].ToString()].MagicalSkillBoost;
            return enKoeff * this.Enchant;
        }

        private int GetEnchantmentDamageReduceKoeff()
        {
            if (!this.Item["name"].ToString().ToLower().Contains("shield")) return 0;

            sbyte enKoeff = ClassEnchantment.ShieldEnchant["shield"].DamageReduce;
            int res = enKoeff * this.Enchant;
            if (res > 20) res = 20;
            return res;
        }

        private int GetEnchantmentBlockKoeff()
        {
            if (!this.Item["name"].ToString().ToLower().Contains("shield")) return 0;

            sbyte enKoeff = ClassEnchantment.ShieldEnchant["shield"].Block;
            if (this.Enchant > 10) return enKoeff * (this.Enchant - 10);
            return 0;
        }

        #endregion

        private void GetEnchantStats()
        {
            ClassEnchantment.EnchantSlots enchantSlot;
            if (!Enum.TryParse(this.Item["equipment_slots"].ToString(), true, out enchantSlot)) return;

            int eValue;
            switch ((int)enchantSlot)
            {
                case 0:
                    eValue = this.GetEnchantmentDefenceKoeff(enchantSlot);
                    this.UpdateEnchantList('e', "physicaldefend", eValue);

                    eValue = this.GetEnchantmentHPKoeff(enchantSlot);
                    this.UpdateEnchantList('e', "maxhp", eValue);

                    eValue = this.GetEnchantmentDefenceResistKoeff(enchantSlot);
                    this.UpdateEnchantList('e', "physicalcriticalreducerate", eValue);

                    eValue = this.GetEnchantmentMagicalBlockKoeff(enchantSlot);
                    this.UpdateEnchantList('e', "magicalblock", eValue);
                    break;
                case 1:
                    eValue = this.GetEnchantmentAttackKoeff();
                    this.UpdateEnchantList('e', "phyattack", eValue);

                    eValue = this.GetEnchantmentMagicBoostKoeff();
                    this.UpdateEnchantList('e', "magicalskillboost", eValue);

                    eValue = this.GetEnchantmentDamageReduceKoeff();
                    this.UpdateEnchantList('e', "damagereduce", eValue);

                    eValue = this.GetEnchantmentBlockKoeff();
                    this.UpdateEnchantList('e', "block", eValue);
                    break;
            }
        }

        #endregion

        #region ManaStones Code

        private void CreateManaStonesTable()
        {
            if (this.Item["cannot_matter_option"].ToString() == "TRUE")
            {
                this.ManastonesVisible = Visibility.Collapsed;
                return;
            }

            byte normalSlots;
            byte bonusSlots;
            byte specialSlots;
            this.GetManaStonesCount(out normalSlots, out bonusSlots, out specialSlots);

            if (normalSlots + bonusSlots + specialSlots == 0)
            {
                this.ManastonesVisible = Visibility.Collapsed;
                return;
            }

            this.ManastonesVisible = Visibility.Visible;
            byte index = 1;

            this.Manastones = new ObservableCollection<ManaStone>();
            for (int i = 0; i < specialSlots; i++)
            {
                this.Manastones.Add(new ManaStone(ManaStone.ManaStoneType.Special, index));
                index++;
            }
            for (int i = 0; i < normalSlots; i++)
            {
                this.Manastones.Add(new ManaStone(ManaStone.ManaStoneType.Normal, index));
                index++;
            }
            for (int i = 0; i < bonusSlots; i++)
            {
                this.Manastones.Add(new ManaStone(ManaStone.ManaStoneType.Bonus, index));
                index++;
            }

            for (int i = 0; i < 6 - normalSlots - bonusSlots - specialSlots; i++)
            {
                this.Manastones.Add(new ManaStone(ManaStone.ManaStoneType.None, index));
                index++;
            }

            this.ManastonesMaxLevel = this.GetManaStonesMaxLevel();

            this.ManastoneText = String.Format(Resources.Manastones_LevelInfo, this.ManastonesMaxLevel);
        }

        private void GetManaStonesCount(out byte normalCount, out byte bonusCount, out byte specialCount)
        {
            normalCount = 0;
            bonusCount = 0;
            specialCount = 0;

            if (!this.Item.Table.Columns.Contains("option_slot_value")
                || String.IsNullOrEmpty(this.Item["option_slot_value"].ToString())) return;

            normalCount = Convert.ToByte(this.Item["option_slot_value"].ToString());

            if (!string.IsNullOrEmpty(this.Item["option_slot_bonus"].ToString())) bonusCount = Convert.ToByte(this.Item["option_slot_bonus"].ToString());

            if (!string.IsNullOrEmpty(this.Item["special_slot_value"].ToString())) specialCount = Convert.ToByte(this.Item["special_slot_value"].ToString());

            if (normalCount + bonusCount + specialCount > 6)
            {
                normalCount = (byte)(6 - bonusCount - specialCount);
            }
        }

        private byte GetManaStonesMaxLevel()
        {
            byte level = Convert.ToByte(this.Item["level"].ToString());

            if (level <= 10)
            {
                return 20;
            }
            if (level <= 20)
            {
                return 30;
            }
            if (level <= 30)
            {
                return 40;
            }
            if (level <= 40)
            {
                return 50;
            }
            return (byte)(level <= 50 ? 60 : 70);
        }

        private void OpenManastone(string stoneNumber)
        {
            byte stoneIndex = Convert.ToByte(stoneNumber);

            ManastonePage mp = new ManastonePage();
            ManastonesDialogViewModel mpvm = (ManastonesDialogViewModel)mp.DataContext;

            ModernDialog md = new ModernDialog { Content = mp, Title = Resources.Manastones_DialogTitle };

            mpvm.CurrentManaStone = this.Manastones[stoneIndex];
            mpvm.MaxLevel = this.ManastonesMaxLevel;
            mpvm.Type = this.Manastones[stoneIndex].SlotType;
            mpvm.Index = this.Manastones[stoneIndex].Index;
            mpvm.Dialog = md;

            md.MaxWidth = 800;
            md.ShowDialog();

            this.Manastones[stoneIndex] = mpvm.CurrentManaStone.CloneLite(
                this.Manastones[stoneIndex].SlotType,
                this.Manastones[stoneIndex].Index);

            if (ReferenceEquals(md.Tag, "CopyManaStone"))
            {
                this.CopyManaStoneToAllSlots(mpvm.CurrentManaStone);
            }
            else
            {
                this.UpdateManastoneStats(this.Manastones[stoneIndex], EnchantStates.Plus);
            }
        }

        private void CopyManaStoneToAllSlots(ManaStone sourceManastone)
        {
            for (int i = 0; i < this.Manastones.Count; i++)
            {
                if (this.Manastones[i].Visible != Visibility.Visible || this.Manastones[i].Index == sourceManastone.Index) continue;

                if (((sourceManastone.SlotType != ManaStone.ManaStoneType.Normal
                      && sourceManastone.SlotType != ManaStone.ManaStoneType.Bonus)
                     || (this.Manastones[i].SlotType != ManaStone.ManaStoneType.Normal
                         && this.Manastones[i].SlotType != ManaStone.ManaStoneType.Bonus))
                    && (sourceManastone.SlotType != ManaStone.ManaStoneType.Special
                        || this.Manastones[i].SlotType != ManaStone.ManaStoneType.Special)) continue;

                this.Manastones[i] = sourceManastone.CloneLite(this.Manastones[i].SlotType, this.Manastones[i].Index);

                this.UpdateManastoneStats(this.Manastones[i], EnchantStates.Plus);
            }


        }

        private void DeleteManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (this.Manastones[index].Row == null) return;

            this.UpdateManastoneStats(this.Manastones[index], EnchantStates.Minus);
            this.Manastones[index] = new ManaStone(this.Manastones[index].SlotType, this.Manastones[index].Index);
        }

        private void CopyManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (this.Manastones[index].Row == null) return;

            this.CopyManaStoneToAllSlots(this.Manastones[index]);
        }

        private void UpdateManastoneStats(ManaStone stone, EnchantStates state)
        {
            for (int i = 1; i < 6; i++)
            {
                if (stone.Row == null || string.IsNullOrEmpty(stone.Row["stat_enchant_type" + i].ToString())) continue;
                this.UpdateEnchantList(
                    'm',
                    stone.Row["stat_enchant_type" + i].ToString().ToLower(),
                    Convert.ToInt32(stone.Row["stat_enchant_value" + i]),
                    0,
                    state);
            }

            this.ShowFullStatsTable();
        }

        public void LoadManastone(byte index, string manastoneName)
        {
            this.Manastones[index] = new ManaStone(
                DataModel.GetRowAtName("MagicStones", manastoneName),
                this.Manastones[index].SlotType) { Index = (byte)(index + 1) };
            this.UpdateManastoneStats(this.Manastones[index], EnchantStates.Plus);
        }

        #endregion

        #region Bonus Code

        private void UpdateStatsFromBonus()
        {
            for (byte i = 1; i < 13; i++)
            {
                string newUnit = "";
                KeyValuePair<String, Single> stat =
                    CardStat.GetStat(this.Item["bonus_attr" + i].ToString());

                if (string.IsNullOrEmpty(stat.Key)) continue;
                if (this.Item["bonus_attr" + i].ToString().Contains("%")) newUnit = "%";
                this.UpdateEnchantList('b', stat.Key, stat.Value, unit: newUnit);
            }
        }

        #endregion

        #region Idian Code

        private void CreateIdianTable()
        {
            if (!this.Item.Table.Columns.Contains("can_polish") || this.IsArmsfusionItem || this.PlaceIndex == 2)
            {
                this.IdianVisible = Visibility.Collapsed;
            }
            else
            {
                this.IdianVisible = this.Item["can_polish"].ToString() == "TRUE"
                    ? Visibility.Visible
                    : Visibility.Collapsed;
                if (this.IdianVisible != Visibility.Visible) return;
            }

            this.IdianText = Resources.Idian_DefaultText;
            this.IdianCharacters = string.Format(Resources.Idian_LevelInfo, this.idianMaxLevel) + "\n\n";

            if (String.IsNullOrEmpty(this.Idian.Name))
            {
                this.IdianCharacters += Resources.Idian_NoEffect;
            }
            else
            {
                ItemTypeColorConverter converter = new ItemTypeColorConverter();
                this.IdianText = string.Format(
                    Resources.Idian_InsertedIdian,
                    this.Idian.Translate,
                    converter.Convert(this.Idian.Quality, null, "TextColor", null));

                IdianRandomTextConverter converter2 = new IdianRandomTextConverter();
                this.IdianCharacters += converter2.Convert(this.Idian.Random1, null, "AccentColor", null);

                string iBonus2 =  converter2.Convert(this.Idian.Random2, null, "AccentColor", null).ToString() ;
                if (!string.IsNullOrWhiteSpace(iBonus2)) this.IdianCharacters += ", " + iBonus2;

                iBonus2 = converter2.Convert(this.Idian.Random3, null, "AccentColor", null).ToString();
                if (!string.IsNullOrWhiteSpace(iBonus2)) this.IdianCharacters += ", " + iBonus2;
            }
        }

        private byte GetIdianMaxLevel()
        {
            byte level = Convert.ToByte(this.Item["level"].ToString());

            if (level <= 10)
            {
                return 20;
            }
            if (level <= 20)
            {
                return 30;
            }
            if (level <= 30)
            {
                return 40;
            }
            if (level <= 40)
            {
                return 50;
            }
            return (byte)(level <= 50 ? 60 : 70);
        }

        private void OpenIdian()
        {
            IdianPage ip = new IdianPage();
            IdianDialogViewModel ipvm = (IdianDialogViewModel)ip.DataContext;

            ModernDialog md = new ModernDialog { Content = ip, Title = Resources.Idian_DialogTitle };

            ipvm.Idian = this.Idian;
            ipvm.MaxLevel = this.idianMaxLevel;
            ipvm.Dialog = md;
            md.MaxWidth = 900;
            md.ShowDialog();

            this.Idian = ipvm.Idian;

            this.GetIdianStats();
        }

        private void GetIdianStats()
        {
            if (String.IsNullOrEmpty(this.Idian.Name))
            {
                foreach (StatsValuesClass enchantClass in this.StatsList)
                {
                    if (Math.Abs(enchantClass.IdianValue - 0) > 0)
                    {
                        this.UpdateEnchantList('i', enchantClass.Stat, enchantClass.IdianValue, 0, EnchantStates.Minus);
                    }

                    enchantClass.IdianValue = 0;
                }
            }

            this.UpdateEnchantList('i', this.Idian.Random1.Key, this.Idian.Random1.Value);
            this.UpdateEnchantList('i', this.Idian.Random2.Key, this.Idian.Random2.Value);
            this.UpdateEnchantList('i', this.Idian.Random3.Key, this.Idian.Random3.Value);
            this.UpdateEnchantList('i', this.Idian.Random4.Key, this.Idian.Random4.Value);
            this.UpdateEnchantList('i', this.Idian.Random5.Key, this.Idian.Random5.Value);
            this.UpdateEnchantList('i', this.Idian.Random6.Key, this.Idian.Random6.Value);
            this.UpdateEnchantList('i', this.Idian.Random7.Key, this.Idian.Random7.Value);
            this.UpdateEnchantList('i', this.Idian.Random8.Key, this.Idian.Random8.Value);

            this.ShowFullStatsTable();
        }

        public void LoadIdian(string idianName)
        {
            this.Idian = new Idian(idianName);
            this.GetIdianStats();
        }

        #endregion

        #region Coins Code

        private void CreateCoinsTable()
        {
            this.AbyssPointsVisible = new List<Visibility>(2);

            if (!string.IsNullOrEmpty(this.Item["extra_currency_item"].ToString()))
            {
                DataRow row = DataModel.GetRowAtName(
                    "Allitems_Coins",
                    this.Item["extra_currency_item"].ToString(),
                    filterField: "coin_name");

                if (row != null)
                {
                    this.ExtraCurrencyIcon = row["icon_name"].ToString();
                    this.ExtraCurrencyName = row["translate" + DataModel.EngFix].ToString();
                    this.AbyssPointsVisible.Add(Visibility.Visible);
                }
                else
                {
                    this.AbyssPointsVisible.Add(Visibility.Collapsed);
                }
            }
            else
            {
                this.ExtraCurrencyIcon = "";
                this.ExtraCurrencyName = "";
                this.AbyssPointsVisible.Add(Visibility.Collapsed); 
            }

            if (this.Item.Table.Columns.Contains("abyss_point"))
            {
                this.AbyssPointsVisible.Add(string.IsNullOrEmpty(this.Item["abyss_point"].ToString())
                                        ? Visibility.Collapsed : Visibility.Visible);
            }
            else
            {
                this.AbyssPointsVisible.Add(Visibility.Collapsed);
            }

            this.OnPropertyChanged("AbyssPointsVisible");

            this.Coins = DataModel.GetCoins(this.Item["name"].ToString());
        }

        #endregion

        #region God Enchant Code

        private void CreateGodEnchantStats()
        {
            this.GodEnchantStats = new List<KeyValuePair<string, float>>();

            for (int i = 1; i <= 4; i++)
            {
                KeyValuePair<string, float> stat = CardStat.GetStat(this.Item["bonus_attr_a"+i].ToString());
                this.GodEnchantStats.Add(new KeyValuePair<string, float>(stat.Key, stat.Value));
            }
            for (int i = 1; i <= 4; i++)
            {
                KeyValuePair<string, float> stat = CardStat.GetStat(this.Item["bonus_attr_b" + i].ToString());
                this.GodEnchantStats.Add(new KeyValuePair<string, float>(stat.Key, stat.Value));
            }
        }

        private void SetGodEnchant()
        {
            if (this.Item.Table.Columns["charge_level"] == null 
                || string.IsNullOrEmpty(this.Item["charge_level"].ToString()))
            {
                this.GodEnchantVisible = Visibility.Collapsed;
                this.GodEnchantLevel = 0;
                this.GodEnchantStats = null;

                this.GodEnchantCharactersLevel1 = "";
                this.GodEnchantCharactersLevel2 = "";

                return;
            }

            this.CreateGodEnchantStats();
            if (IsArmsfusionItem)
            {
                this.GodEnchantVisible = Visibility.Collapsed;
                return;
            }
            
            this.GodEnchantVisible = Visibility.Visible;
            this.GodEnchantMaxLevel = Convert.ToByte(this.Item["charge_level"]);

            CreateGodEnchantTable();
        }

        private void CreateGodEnchantTable()
        {
            this.GodEnchantCharactersLevel1 = "";
            this.GodEnchantCharactersLevel2 = "";

            if (this.GodEnchantMaxLevel == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            this.GodEnchantCharactersLevel1 = string.Format(Resources.GodEnchant_CondiEffect, "1") + "\n";

            SetGodEnchantCharactersOpacity();

            string caret = "\t  ";
            for (int i = 0; i <= 3; i++)
            {
                this.GodEnchantCharactersLevel1 += converter.Convert(this.GodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }

            if (this.GodEnchantMaxLevel <= 1) return;

            this.GodEnchantCharactersLevel2 = string.Format(Resources.GodEnchant_CondiEffect, "2") + "\n";

            caret = "\t";
            for (int i = 4; i <= 7; i++)
            {
                this.GodEnchantCharactersLevel2 += converter.Convert(this.GodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }
        }

        public void SetGodEnchantLevel(string sLevel)
        {
            this.GodEnchantLevel = Convert.ToByte(sLevel);
        }

        private void SetGodEnchantCharactersOpacity()
        {
            this.GodEnchantLevelsOpacity = new[] { 0.4f, 0.4f };

            if (this.GodEnchantLevel > 0) this.GodEnchantLevelsOpacity[0] = 1;
            if (this.GodEnchantLevel > 1) this.GodEnchantLevelsOpacity[1] = 1;

            this.OnPropertyChanged("GodEnchantLevelsOpacity");
        }

        private void GetGodEnchantStats()
        {
            if (this.godEnchantLevel == 0)
            {
                foreach (StatsValuesClass enchantClass in this.StatsList.Where(enchantClass => Math.Abs(enchantClass.GodEnchantValue - 0) > 0))
                {
                    this.UpdateEnchantList('g', enchantClass.Stat, enchantClass.GodEnchantValue, 0, EnchantStates.Minus);
                }
            }

            if (this.godEnchantLevel > 0 && GodEnchantStats != null)
            {
                this.UpdateEnchantList('g', this.GodEnchantStats[0].Key, this.GodEnchantStats[0].Value);
                this.UpdateEnchantList('g', this.GodEnchantStats[1].Key, this.GodEnchantStats[1].Value);
                this.UpdateEnchantList('g', this.GodEnchantStats[2].Key, this.GodEnchantStats[2].Value);
                this.UpdateEnchantList('g', this.GodEnchantStats[3].Key, this.GodEnchantStats[3].Value);
            }

            if (this.godEnchantLevel > 0 && ArmsfusionGodEnchantStats != null)
            {
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[0].Key, this.ArmsfusionGodEnchantStats[0].Value);
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[1].Key, this.ArmsfusionGodEnchantStats[1].Value);
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[2].Key, this.ArmsfusionGodEnchantStats[2].Value);
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[3].Key, this.ArmsfusionGodEnchantStats[3].Value);
            }
            
            if (this.godEnchantLevel > 1 && GodEnchantStats != null)
            {
                this.UpdateEnchantList('g', this.GodEnchantStats[4].Key, this.GodEnchantStats[4].Value, 0, EnchantStates.Plus);
                this.UpdateEnchantList('g', this.GodEnchantStats[5].Key, this.GodEnchantStats[5].Value, 0, EnchantStates.Plus);
                this.UpdateEnchantList('g', this.GodEnchantStats[6].Key, this.GodEnchantStats[6].Value, 0, EnchantStates.Plus);
                this.UpdateEnchantList('g', this.GodEnchantStats[7].Key, this.GodEnchantStats[7].Value, 0, EnchantStates.Plus);
            }

            if (this.godEnchantLevel > 1 && ArmsfusionGodEnchantStats != null)
            {
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[4].Key, this.ArmsfusionGodEnchantStats[4].Value, 0, EnchantStates.Plus);
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[5].Key, this.ArmsfusionGodEnchantStats[5].Value, 0, EnchantStates.Plus);
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[6].Key, this.ArmsfusionGodEnchantStats[6].Value, 0, EnchantStates.Plus);
                this.UpdateEnchantList('g', this.ArmsfusionGodEnchantStats[7].Key, this.ArmsfusionGodEnchantStats[7].Value, 0, EnchantStates.Plus);
            }


            this.ShowFullStatsTable();
        }

        #endregion

        #region Random Bonus Code

        private void CreateRandomBonusTable()
        {
            if (!this.Item.Table.Columns.Contains("random_option_set"))
            {
                this.RandomBonusVisible = Visibility.Collapsed;
            }
            else
            {
                this.RandomBonusVisible = !string.IsNullOrEmpty(this.Item["random_option_set"].ToString())
                    ? Visibility.Visible
                    : Visibility.Collapsed;
                if (this.RandomBonusVisible != Visibility.Visible) return;
            }

            this.RandomBonusText = Resources.RandomBonus_DefaultText;
            this.RandomBonusCharacters = Resources.RandomBonus_NotSelected;

            if (this.RandomBonus == null)
            {
                return;
            }

            this.RandomBonusText = string.Format(Resources.RandomBonus_Selected, this.RandomBonus.Chance);

            this.RandomBonusCharacters = this.RandomBonusText + ":\n";
            IdianRandomTextConverter converter = new IdianRandomTextConverter();
            foreach (KeyValuePair<string, float> bonus in this.RandomBonus.RandomBonuses.Where(bonus => !string.IsNullOrEmpty(bonus.Key)))
            {
                this.RandomBonusCharacters += (string)converter.Convert(bonus, null, "AccentColor", null) + ", ";
            }
            this.RandomBonusCharacters = this.RandomBonusCharacters.Remove(this.RandomBonusCharacters.Length-2, 2);
        }

        private void OpenRandomBonus()
        {
            RandomBonusPage rbPage = new RandomBonusPage();
            RandomBonusViewModel rbViewModel = (RandomBonusViewModel)rbPage.DataContext;

            ModernDialog md = new ModernDialog { Content = rbPage, Title = Resources.RandomBonus_DialogTitle };
            
            rbViewModel.LoadRandomBonusList(this.Item["random_option_set"].ToString(), this.randomBonus);
            rbViewModel.Dialog = md;
            md.MaxWidth = 900;
            md.ShowDialog();

            this.RandomBonus = rbViewModel.SelectedRandomBonus;

            this.GetRandomBonusStats();
        }

        private void GetRandomBonusStats()
        {
            if (this.RandomBonus == null)
            {
                foreach (StatsValuesClass enchantClass in this.StatsList)
                {
                    if (Math.Abs(enchantClass.RandomBonusValue - 0) > 0)
                    {
                        this.UpdateEnchantList('r', enchantClass.Stat, enchantClass.RandomBonusValue, 0, EnchantStates.Minus);
                    }

                    enchantClass.RandomBonusValue = 0;
                }
            }
            else
            {
                foreach (KeyValuePair<string, float> bonus in this.RandomBonus.RandomBonuses)
                {
                    this.UpdateEnchantList('r', bonus.Key, bonus.Value);
                }
            }
            
            this.ShowFullStatsTable();
        }

        public void LoadRandomBonus(string id)
        {
            this.RandomBonus = new RandomBonus(id, this.Item["random_option_set"].ToString());
            this.GetRandomBonusStats();
        }

        #endregion

        #region ItemSet

        private void GetItemSet(ItemSets itemSets)
        {
            if (this.Item == null) return;
            ItemSet statusItemSet = null;

            if (itemSets == null)
            {
                if (this.ItemSet == null)
                {
                    string[] itemInfo = { this.Item["name"].ToString(), this.Item.Table.TableName };
                    statusItemSet = ItemSet.GetItemSet(itemInfo);
                }
            }
            else
            {
                statusItemSet = itemSets.GetItemSet(this.Item["name"].ToString());
            }
           
            this.ItemSet = statusItemSet;
            this.CreateItemSetTable();
        }

        private void CreateItemSetTable()
        {
            if (this.ItemSet == null)
            {
                this.ItemSetVisible = Visibility.Collapsed;
                return;
            }

            this.ItemSetVisible = Visibility.Visible;
            this.ItemSetText = this.ItemSet.GetTranslate();

            this.ItemSetCharacters = this.ItemSet.GetCharacters(this.TranslateColor);
        }

        #endregion

        #region Armsfusion

        public void LoadArmsfusionCard(Card3ViewModel armsfusionCard)
        {
            if (StatsList == null) return;

            foreach (StatsValuesClass stat in StatsList)
            {
                stat.ArmsfusionBonusValue = 0;
                stat.ArmsfusionManaStoneValue = 0;
            }

            if (armsfusionCard == null || armsfusionCard.Item == null)
            {
                ArmsfusionItem = null;
                ArmsfusionBonusCharacters = null;
                ArmsfusionManastones = null;
                return;
            }
            
            ArmsfusionItem = armsfusionCard.Item;
            ArmsfusionBonusCharacters = armsfusionCard.BonusCharacters;
            this.ArmsfusionBonusVisible = string.IsNullOrEmpty(this.ArmsfusionBonusCharacters) ? Visibility.Collapsed : Visibility.Visible;
            foreach (StatsValuesClass armsfusionStat in armsfusionCard.StatsList.Where(armsfusionStat => armsfusionStat.BonusValue > 0))
            {
                this.UpdateEnchantList('a', armsfusionStat.Stat, armsfusionStat.BonusValue, unit: armsfusionStat.Unit);
            }

            ArmsfusionManastoneText = armsfusionCard.ManastoneText;
            armsfusionManastonesMaxLevel = armsfusionCard.ManastonesMaxLevel;
            this.ArmsfusionManastonesVisible = armsfusionManastonesMaxLevel > 0 ? Visibility.Visible : Visibility.Collapsed;
            armsfusionManastones = armsfusionCard.Manastones;
            foreach (StatsValuesClass armsfusionStat in armsfusionCard.StatsList.Where(armsfusionStat => armsfusionStat.ManaStoneValue > 0))
            {
                this.UpdateEnchantList('n', armsfusionStat.Stat, armsfusionStat.ManaStoneValue, unit: armsfusionStat.Unit, state: EnchantStates.Plus);
            }

            ArmsfusionTitleColor = armsfusionCard.TranslateColor;
            ArmsfusionGodEnchantStats = armsfusionCard.GodEnchantStats;

            SetArmsfusion();
        }

        private void SetArmsfusion()
        {
            if (ArmsfusionItem == null)
            {
                ArmsfusionVisible = Visibility.Collapsed;
                return;
            }

            ArmsfusionVisible = Visibility.Visible;
            Byte armsfusionGodEnchantMaxLevel = string.IsNullOrEmpty(this.ArmsfusionItem["charge_level"].ToString()) ? (byte)0 : Convert.ToByte(this.ArmsfusionItem["charge_level"]);

            if (armsfusionGodEnchantMaxLevel > 0)
            {
                this.GodEnchantMaxLevel = string.IsNullOrEmpty(this.Item["charge_level"].ToString())
                    ? (byte)0
                    : Convert.ToByte(this.Item["charge_level"]);

                this.CreateGodEnchantTable();
                if (armsfusionGodEnchantMaxLevel > godEnchantMaxLevel)
                {
                    this.GodEnchantVisible = Visibility.Visible;
                    this.GodEnchantMaxLevel = armsfusionGodEnchantMaxLevel;
                }

                AddGodEnchantTableFromArmsfusion();
                this.ShowFullStatsTable();
            }
        }

        private void OpenArmsfusionManastone(string stoneNumber)
        {
            byte stoneIndex = Convert.ToByte(stoneNumber);

            ManastonePage mp = new ManastonePage();
            ManastonesDialogViewModel mpvm = (ManastonesDialogViewModel)mp.DataContext;

            ModernDialog md = new ModernDialog { Content = mp, Title = Resources.Manastones_DialogTitle };

            mpvm.CurrentManaStone = this.ArmsfusionManastones[stoneIndex];
            mpvm.MaxLevel = this.armsfusionManastonesMaxLevel;
            mpvm.Type = this.ArmsfusionManastones[stoneIndex].SlotType;
            mpvm.Index = this.ArmsfusionManastones[stoneIndex].Index;
            mpvm.Dialog = md;

            md.MaxWidth = 800;
            md.ShowDialog();

            this.ArmsfusionManastones[stoneIndex] = mpvm.CurrentManaStone.CloneLite(
                this.ArmsfusionManastones[stoneIndex].SlotType,
                this.ArmsfusionManastones[stoneIndex].Index);

            if (ReferenceEquals(md.Tag, "CopyManaStone"))
            {
                this.CopyArmsfusionManaStoneToAllSlots(mpvm.CurrentManaStone);
            }
            else
            {
                this.UpdateArmsfusionManastoneStats(this.ArmsfusionManastones[stoneIndex], EnchantStates.Plus);
            }
        }

        private void CopyArmsfusionManaStoneToAllSlots(ManaStone sourceManastone)
        {
            for (int i = 0; i < this.ArmsfusionManastones.Count; i++)
            {
                if (this.ArmsfusionManastones[i].Visible != Visibility.Visible || this.ArmsfusionManastones[i].Index == sourceManastone.Index) continue;

                if (((sourceManastone.SlotType != ManaStone.ManaStoneType.Normal
                      && sourceManastone.SlotType != ManaStone.ManaStoneType.Bonus)
                     || (this.ArmsfusionManastones[i].SlotType != ManaStone.ManaStoneType.Normal
                         && this.ArmsfusionManastones[i].SlotType != ManaStone.ManaStoneType.Bonus))
                    && (sourceManastone.SlotType != ManaStone.ManaStoneType.Special
                        || this.ArmsfusionManastones[i].SlotType != ManaStone.ManaStoneType.Special)) continue;

                this.ArmsfusionManastones[i] = sourceManastone.CloneLite(this.ArmsfusionManastones[i].SlotType, this.ArmsfusionManastones[i].Index);

                this.UpdateArmsfusionManastoneStats(this.ArmsfusionManastones[i], EnchantStates.Plus);
            }
        }

        private void UpdateArmsfusionManastoneStats(ManaStone stone, EnchantStates state)
        {
            for (int i = 1; i < 6; i++)
            {
                if (stone.Row == null || string.IsNullOrEmpty(stone.Row["stat_enchant_type" + i].ToString())) continue;
                this.UpdateEnchantList(
                    'n',
                    stone.Row["stat_enchant_type" + i].ToString().ToLower(),
                    Convert.ToInt32(stone.Row["stat_enchant_value" + i]),
                    0,
                    state);
            }

            this.ShowFullStatsTable();
        }

        private void DeleteArmsfusionManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (this.ArmsfusionManastones[index].Row == null) return;

            this.UpdateArmsfusionManastoneStats(this.ArmsfusionManastones[index], EnchantStates.Minus);
            this.ArmsfusionManastones[index] = new ManaStone(this.ArmsfusionManastones[index].SlotType, this.ArmsfusionManastones[index].Index);
        }

        private void CopyArmsfusionManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (this.ArmsfusionManastones[index].Row == null) return;

            this.CopyArmsfusionManaStoneToAllSlots(this.ArmsfusionManastones[index]);
        }

        private void AddGodEnchantTableFromArmsfusion()
        {
            if (ArmsfusionGodEnchantStats == null) return;
            
            CharacterTextConverter converter = new CharacterTextConverter();
            Byte armsfusionGodEnchantMaxLevel = Convert.ToByte(this.ArmsfusionItem["charge_level"]);
            
            if (!string.IsNullOrEmpty(GodEnchantCharactersLevel1)) this.GodEnchantCharactersLevel1 += "\n";
            this.GodEnchantCharactersLevel1 += string.Format(Resources.GodEnchant_CondiEffectAdd, "1") + "\n";

            string caret = "\t  ";
            for (int i = 0; i <= 3; i++)
            {
                this.GodEnchantCharactersLevel1 += converter.Convert(this.ArmsfusionGodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }
            
            if (armsfusionGodEnchantMaxLevel <= 1) return;

            if (!string.IsNullOrEmpty(GodEnchantCharactersLevel2)) this.GodEnchantCharactersLevel2 += "\n";
            this.GodEnchantCharactersLevel2 += string.Format(Resources.GodEnchant_CondiEffectAdd, "2") + "\n";

            caret = "\t";
            for (int i = 4; i <= 7; i++)
            {
                this.GodEnchantCharactersLevel2 += converter.Convert(this.ArmsfusionGodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }
        }

        #endregion
    }
}
